# -*- coding:utf-8 -*-
import base64
import smtplib
import email
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import formataddr
from typing import List, Optional, Union
import os
from config import ROOT_DIR

# test_path = os.path.join(ROOT_DIR, 'Datas/business_continued_provision','test.xlsx')

class EmailSender:
    """
    邮件发送工具类

    功能特点：
    1. 支持SMTP和SMTP_SSL两种连接方式
    2. 支持文本和HTML格式邮件
    3. 支持添加多个附件
    4. 支持收件人、抄送、密送
    5. 自动生成Message-ID和日期
    6. 完善的错误处理和日志输出
    """

    def __init__(
            self,
            smtp_server: str,
            smtp_port: int,
            username: str,
            password: str,
            use_ssl: bool = False,
            timeout: int = 10,
            sender_name: Optional[str] = None,
            reply_to: Optional[str] = None,

    ):
        """
        初始化邮件发送器

        :param smtp_server: SMTP服务器地址
        :param smtp_port: SMTP服务器端口
        :param username: 邮箱用户名
        :param password: 邮箱密码或授权码
        :param use_ssl: 是否使用SSL加密连接
        :param timeout: 连接超时时间(秒)
        :param sender_name: 发件人显示名称
        :param reply_to: 回信地址
        """
        self.smtp_server = smtp_server
        self.smtp_port = smtp_port
        self.username = username
        self.password = password
        self.use_ssl = use_ssl
        self.timeout = timeout
        self.sender_name = sender_name or username
        self.reply_to = reply_to or username
        self.client = None

    def _connect(self) -> bool:
        """建立SMTP连接"""
        try:
            if self.use_ssl:
                self.client = smtplib.SMTP_SSL(
                    self.smtp_server,
                    self.smtp_port,
                    timeout=self.timeout
                )
                print(f"SMTP_SSL连接服务器成功({self.smtp_server}:{self.smtp_port})")
            else:
                self.client = smtplib.SMTP(
                    self.smtp_server,
                    self.smtp_port,
                    timeout=self.timeout
                )
                print(f"SMTP连接服务器成功({self.smtp_server}:{self.smtp_port})")

            self.client.login(self.username, self.password)
            print("账号验证成功")
            return True

        except smtplib.SMTPException as e:
            print(f"SMTP连接或登录失败: {str(e)}")
            return False
        except Exception as e:
            print(f"连接服务器失败: {str(e)}")
            return False

    def _disconnect(self):
        """关闭SMTP连接"""
        if self.client:
            try:
                self.client.quit()
            except:
                self.client.close()
            finally:
                self.client = None

    def _format_addr(self, addr: str, name: Optional[str] = None) -> str:
        """格式化邮箱地址，添加显示名称"""
        if name:
            return formataddr((name, addr))
        return addr

    def _prepare_message(
            self,
            subject: str,
            content: str,
            to_addrs: Union[str, List[str]],
            cc_addrs: Optional[Union[str, List[str]]] = None,
            bcc_addrs: Optional[Union[str, List[str]]] = None,
            attachments: Optional[List[str]] = None,
            content_type: str = "plain"
    ) -> Optional[MIMEMultipart]:
        """
        准备邮件消息

        :return: 构建好的MIMEMultipart对象，失败返回None
        """
        # 处理地址参数
        if isinstance(to_addrs, str):
            to_addrs = [to_addrs]
        if isinstance(cc_addrs, str):
            cc_addrs = [cc_addrs]
        if isinstance(bcc_addrs, str):
            bcc_addrs = [bcc_addrs]

        cc_addrs = cc_addrs or []
        bcc_addrs = bcc_addrs or []
        attachments = attachments or []

        try:
            # 创建邮件消息
            msg = MIMEMultipart('alternative')

            # 邮件头信息
            msg['From'] = self._format_addr(self.username, self.sender_name)
            msg['Reply-to'] = self.reply_to
            msg['To'] = ', '.join(to_addrs)
            if cc_addrs:
                msg['Cc'] = ', '.join(cc_addrs)
            msg['Message-ID'] = email.utils.make_msgid()
            msg['Date'] = email.utils.formatdate()
            msg['Subject'] = subject

            # 添加邮件正文
            body = MIMEText(content, content_type, "utf-8")
            msg.attach(body)

            # 添加附件
            for attachment in attachments or []:
                try:
                    if isinstance(attachment, dict):
                        # 处理字典形式的附件
                        file_name = attachment['filename']
                        file_content = attachment['content']
                        mime_type = attachment.get('mimetype', 'application/octet-stream')
                    else:
                        # 处理字符串路径形式的附件
                        if not os.path.exists(attachment):
                            print(f"附件不存在: {attachment}")
                            continue

                        file_name = os.path.basename(attachment)
                        with open(attachment, 'rb') as f:
                            file_content = f.read()

                        # 根据文件扩展名设置正确的MIME类型
                        _, ext = os.path.splitext(file_name.lower())
                        mime_type = {
                            '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
                            '.xls': 'application/vnd.ms-excel',
                            # 可以添加其他文件类型的MIME类型
                        }.get(ext, 'application/octet-stream')

                    # 使用MIMEApplication处理二进制附件
                    part = MIMEApplication(file_content, _subtype=mime_type.split('/')[-1])

                    # 处理文件名编码（特别是中文文件名）
                    file_name = email.header.Header(file_name, 'utf-8').encode()

                    part.add_header('Content-Disposition', 'attachment',
                                    filename=file_name)
                    part.add_header('Content-Type', mime_type,
                                    name=file_name)

                    msg.attach(part)
                    print(f"已添加附件: {file_name}")

                except Exception as e:
                    print(f"添加附件失败: {str(e)}")
                    continue

            return msg

        except Exception as e:
            print(f"构建邮件消息失败: {str(e)}")
            return None

    def send_email(
            self,
            subject: str,
            content: str,
            to_addrs: Union[str, List[str]],
            cc_addrs: Optional[Union[str, List[str]]] = None,
            bcc_addrs: Optional[Union[str, List[str]]] = None,
            attachments: Optional[List[str]] = None,
            content_type: str = "plain"
    ) -> bool:
        """
        发送邮件

        :return: 是否发送成功
        """
        # 准备邮件消息
        msg = self._prepare_message(
            subject=subject,
            content=content,
            to_addrs=to_addrs,
            cc_addrs=cc_addrs,
            bcc_addrs=bcc_addrs,
            attachments=attachments,
            content_type=content_type
        )

        if not msg:
            return False

        # 获取所有收件人
        if isinstance(to_addrs, str):
            to_addrs = [to_addrs]
        if isinstance(cc_addrs, str):
            cc_addrs = [cc_addrs]
        if isinstance(bcc_addrs, str):
            bcc_addrs = [bcc_addrs]

        cc_addrs = cc_addrs or []
        bcc_addrs = bcc_addrs or []
        recipients = to_addrs + cc_addrs + bcc_addrs

        # 发送邮件
        try:
            if not self._connect():
                return False

            self.client.sendmail(
                self.username,
                recipients,
                msg.as_string()
            )
            print("邮件发送成功")
            return True

        except smtplib.SMTPException as e:
            print(f"邮件发送失败: {str(e)}")
            return False
        except Exception as e:
            print(f"发送过程中发生错误: {str(e)}")
            return False
        finally:
            self._disconnect()

def zi_send_email(source_file,provision_file_name,now_date):
    # 配置SMTP信息（以阿里企业邮箱为例）
    smtp_config = {
        "smtp_server": "smtp.qiye.aliyun.com",
        "smtp_port": 465,
        "username": "gxxxxxxxxx@kinslot.com",
        "password": "xxxxxxxxxxxx",
        "use_ssl": True,
        "sender_name": "金穗隆（广州）",
        "reply_to": "gxxxxxxxxx@kinslot.com"
    }

    # 创建邮件发送器实例
    email_sender = EmailSender(**smtp_config)


    # 发送HTML邮件带附件
    html_content = f"""
        <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>续报备信息</title>
        <style type="text/css">
            body {{
                font-family: Arial, sans-serif;
                line-height: 1.6;
                color: #000000;
            }}
        </style>
    </head>
    <body>
        <!-- 邮件正文 -->
        <div style="font-size:14px; margin-bottom:20px;">
            <p>吴经理，您好：</p>
            <p style="text-indent:2em;">附件是续报备信息，请查收。帮忙续报备，谢谢~~</p>
            <p style="text-align:left;">{now_date}</p>
        </div>

        <!-- 分隔线 -->
        <hr style="border:0; height:1px; background-color:#ddd; margin:20px 0;">

        <!-- 发件人信息 -->
        <div style="font-size:13px; margin-bottom:20px;line-height:1;">
            <p><strong>xxx</strong>&nbsp;&nbsp;&nbsp;&nbsp;<strong>商务助理</strong></p>
        </div>

        <!-- 邮件签名 -->
        <div style="margin-bottom:20px;">
            <table cellpadding="0" cellspacing="0" border="0" style="width:100%;">
                <tr>
                    <td valign="middle">
                        <img src="" alt="公司LOGO" style="height:30px; vertical-align:middle;">
                        <span style="font-size:14px; vertical-align:bottom;">证券代码：839142</span>
                    </td>
                </tr>
                <tr>
                    <td style="font-size:13px; font-weight:; padding:5px 0;">
                        金穗隆（广州）信息科技有限公司
                    </td>
                </tr>
            </table>

            <!-- 分隔线 -->
            <hr style="border:0; height:1px; background-color:#ddd; margin:10px 0;">

            <!-- 联系方式 -->
            <div style="font-size:12px; color:#000000; line-height:0.5;">
                <p>地址：广州市天河北路xxxxxxxxxx楼</p>
                <p>电话：xxxxxxxxxx</p>
                <p>传真：xxxxxxxxxxxx</p>
                <p>邮件：xxxxxxxxxx@kinslot.com</p>
                <p>官网：www.kinslot.com</p>
            </div>
        </div>

        <!-- 声明内容 -->
        <div style="font-size:10px; color:#999999; line-height:1.2; margin-top:30px;">
            <p>声明(DISCLAIMER):</p>
            <p style="text-indent:2em;">本邮件及其附件含有广州金穗隆信息科技股份有限公司的商业信息，仅限于发送给上面地址中列出的个人或群组。禁止任何人未经发件人许可以任何形式（包括但不限于全部或部分地泄露、复制、或散发）不当使用本邮件中的信息。如果您错收了本邮件，请您立即电话或邮件通知发件人并删除本邮件！广州金穗隆信息科技股份有限公司保留对此邮件的最终解释权。</p>
            <p style="text-indent:2em;">This e-mail and its attachments containing Guanzhou Kinslot Information Technology Co.,Ltd. business information, only limited to send to the address above listed individuals or groups. To prohibit any person from any form (including but not limited to all or part of the disclosure, copying or distribution) of the information in this message. If you have received this email in error, please notify the sender by phone or email immediately and delete this message! Guangzhou geoloong information Polytron Technologies Inc reserves the right of final interpretation of this mail.</p>
        </div>
    </body>
    </html>
        """

    email_sender.send_email(
        subject=f"续报备{provision_file_name.split('.')[0]}",
        content=html_content,
        to_addrs="xxxxxxxxxxx@cn.ricoh.com",
        cc_addrs=["xxxxxxxxxxxxxx@kinslot.com","xxxxxxxxxxxxxx@cn.ricoh.com"],
        content_type="html",
        attachments=[source_file]
    )


def zong_send_email(source_file,provision_file_name,now_date):
    # 配置SMTP信息（以阿里企业邮箱为例）
    smtp_config = {
        "smtp_server": "smtp.qiye.aliyun.com",
        "smtp_port": 465,
        "username": "xxxxxxxxxxxxxxx@kinslot.com",
        "password": "xxxxxxxxxxxxxxxx",
        "use_ssl": True,
        "sender_name": "金穗隆总公司",
        "reply_to": "xxxxxxxxxxxxxxx@kinslot.com"
    }

    # 创建邮件发送器实例
    email_sender = EmailSender(**smtp_config)


    # 发送HTML邮件带附件
    html_content = f"""
        <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>续报备信息</title>
        <style type="text/css">
            body {{
                font-family: Arial, sans-serif;
                line-height: 1.6;
                color: #000000;
            }}
        </style>
    </head>
    <body>
        <!-- 邮件正文 -->
        <div style="font-size:14px; margin-bottom:20px;">
            <p>吴经理，您好：</p>
            <p style="text-indent:2em;">附件是续报备信息，请查收。帮忙续报备并回复，谢谢~~</p>
            <p style="text-align:left;">{now_date}</p>
        </div>

        <!-- 分隔线 -->
        <hr style="border:0; height:1px; background-color:#ddd; margin:20px 0;">

        <!-- 发件人信息 -->
        <div style="font-size:13px; margin-bottom:20px;line-height:1;">
            <p><strong>xxxxxxxxxxxx@kinslot.com</strong></p>
        </div>
    </body>
    </html>
        """

    email_sender.send_email(
        subject=f"续报备{provision_file_name.split('.')[0]}",
        content=html_content,
        to_addrs="xxxxxxxxxxxxx@cn.ricoh.com",
        cc_addrs="xxxxxxxxxxxxxx@kinslot.com",
        content_type="html",
        attachments=[source_file]
    )

